﻿using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using SD.Database.Classes;
using System.Collections.Generic;
using DBAccess;

namespace SD.Database
{
    public partial class UserFunctions
    {
        public static DataSet NewsForPlayer(int pId)
        {
            //TODO: Add time support here
            return TimeHelper.ChangeTime(DAL.GetInstance().GetData("Select NewsDate, Message From News Where PlayerId = @param0 order by NewsDate desc", new List<object>() { pId }), pId);
        }
        public static DataSet PlanetsForPlayer(int pId)
        {
            return DAL.GetInstance().GetData("Select * From Planets Where PlayerId = @param0", new List<object>() { pId });
        }

        public static int FleetOwner(int systemId, int planetId)
        {
            return DAL.GetInstance().GetInt("SELECT FleetOwnerID FROM Planets Where PlanetID = @param0 and SystemId = @param1", new List<object>() { planetId, systemId });
        }

        public static int GetPlayerAlliance(int id)
        {
            return DAL.GetInstance().GetInt("Select AllianceID From AllianceMembers Where PlayerID = @param0", new List<object>() { id });
        }

        public static List<int> GetPlayerIDs()
        {
            List<int> tmp = new List<int>();
            DataSet ds = DAL.GetInstance().GetData("Select PlayerID From Players Where PlayerId > 1");

            foreach (DataRow row in ds.Tables[0].Rows)
            {
                tmp.Add(int.Parse(row[0].ToString()));
            }
            return tmp;
        }
        public static double GetBonusForProduction(int pId)
        {
            double bonus = 0;
            //get bonus from race
            double prodBonus = double.Parse(Configuration.GetConfigurationForOption("ProductionBonus"));
            bonus += prodBonus * GetPlayerInt(pId, "Production");
            string artifact = UsedArtifact(pId);
            switch (artifact)
            {
                case "CS": bonus += 0.1; break;
                case "RF": bonus += 0.2; break;
                case "NF": bonus += 0.3; break;
                case "STr": bonus -= 0.15; break;
            }
            return bonus;
        }
        public static double GetBonusForCulture(int pId)
        {
            double bonus = 0;
            //get bonus from race
            double prodBonus = double.Parse(Configuration.GetConfigurationForOption("CultureBonus"));
            bonus += prodBonus * GetPlayerInt(pId, "Culture");
            string artifact = UsedArtifact(pId);
            switch (artifact)
            {
                case "GT": bonus += 0.1; break;
                case "ITV": bonus += 0.2; break;
                case "STr": bonus += 0.1; break;
                case "BHS": bonus -= 0.1; break;
                case "AF": bonus -= 0.3; break;
                case "MOT": bonus += 0.2; break;
            }
            return bonus;
        }
        public static double GetBonusForScience(int pId)
        {
            double bonus = 0;
            //get bonus from race
            double prodBonus = double.Parse(Configuration.GetConfigurationForOption("ScienceBonus"));
            bonus += prodBonus * GetPlayerInt(pId, "Science");
            string artifact = UsedArtifact(pId);
            switch (artifact)
            {
                case "AL": bonus += 0.1; break;
                case "GL": bonus += 0.2; break;
                case "AML": bonus += 0.3; break;
                case "BHS": bonus += 0.45; break;
                case "AF": bonus -= 0.45; break;
                case "MOT": bonus += 0.2; break;
            }
            if (PlayerHasSpecialBulding(pId, SpecialBuldings.ScienceNetwork) == true)
            {
                bonus += 0.15;
            }
            return bonus;
        }
        public static double GetBonusForGrowth(int pId)
        {
            double bonus = 0;
            //get bonus from race
            double prodBonus = double.Parse(Configuration.GetConfigurationForOption("GrowthBonus"));
            bonus += prodBonus * GetPlayerInt(pId, "Growth");
            string artifact = UsedArtifact(pId);
            switch (artifact)
            {
                case "E1": bonus += 0.1; break;
                case "E2": bonus += 0.2; break;
                case "E3": bonus += 0.3; break;
                case "STr": bonus += 0.2; break;
                case "BHS": bonus -= 0.1; break;
                case "AF": bonus -= 0.45; break;
                case "MOT": bonus += 0.2; break;
            }
            return bonus;
        }
        public static int SciencePercentage(int pId, string science)
        {
            return (int)(100 * (UserFunctions.GetPlayerFloat(pId, science) - (int)UserFunctions.GetPlayerFloat(pId, science)));
        }
        public static string UsedArtifact(int pId)
        {
            return DAL.GetInstance().GetScalar("Select ArtifactId From Players Where PlayerId = @param0", new List<object> { pId });
        }
        public static List<string> PossibleArtifacts(int pId)
        {
            List<string> bought = PlayerArtifacts(pId);
            List<string> tmp = new List<string>();
            foreach (string t in ArtifactsFunctions.ArtifactsList)
            {
                if (ArtifactsFunctions.Prerequisites(pId, t) == true && bought.Contains(t) == false)
                    tmp.Add(t);
            }
            return tmp;
        }
        public static List<string> PlayerArtifacts(int pId)
        {
            List<string> tmp = new List<string>();
            DataSet ds = DAL.GetInstance().GetData("Select ArtifactId From Artifacts Where PlayerId = @param0", new List<object>() { pId });
            if (ds.Tables.Count > 0)
                foreach (DataRow row in ds.Tables[0].Rows)
                    tmp.Add(row[0].ToString());

            return tmp;
        }
        public static bool PlayerHasSpecialBulding(int pId, SpecialBuldings type)
        {
            string command;
            switch (type)
            {
                case SpecialBuldings.SpyAcademy: command = "Select Academy From Players where PlayerId = @param0";
                    break;
                case SpecialBuldings.OrbitalCC: command = "Select OrbitalCenter From Players where PlayerId = @param0";
                    break;
                case SpecialBuldings.AllianceCC: command = "Select AllianceCenter From Players where PlayerId = @param0";
                    break;
                case SpecialBuldings.Market: command = "Select Market From Players where PlayerId = @param0";
                    break;
                case SpecialBuldings.ScienceNetwork: command = "Select ScienceNetwork From Players where PlayerId = @param0";
                    break;
                default:
                    return false;
            }
            string tmp = DAL.GetInstance().GetScalar(command, new List<object>() { pId });
            if (tmp == "1") return true;
            bool returnValue;
            if (bool.TryParse(tmp, out returnValue) == true)
                return returnValue;
            else
                return false;
        }
        public static Dictionary<string, string> GetPlayerPlanets(int pId)
        {
            Dictionary<string, string> tmp = new Dictionary<string, string>();
            DataSet ds = DAL.GetInstance().GetData("SELECT Systems.SystemName, Planets.PlanetID, Planets.SystemID FROM Systems INNER JOIN Planets ON Systems.SystemID = Planets.SystemID WHERE (Planets.OwnerID = @param0)", new List<object>() { pId });
            if (ds.Tables.Count > 0)
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    tmp.Add(row[2].ToString() + ";" + row[1].ToString(), row[0].ToString() + " #" + row[1].ToString());
                }
            return tmp;
        }
        public static int EcoBonus(int pId)
        {
            int eco = (int)GetPlayerFloat(pId, "Economy");
            return (int)Math.Floor(eco / 4.0);
        }
        public static int PlayerCurrentScience(int id)
        {
            return GetPlayerInt(id, "CurrentScience");
        }
        public static string PlayerName(int id)
        {
            return DAL.GetInstance().GetScalar("SELECT PlayerName FROM Players WHERE (PlayerId  = @param0 )", new List<object>() { id });
        }
        public static bool UserExists(string name)
        {
            if (DAL.GetInstance().GetInt("SELECT Count(*) FROM Players WHERE (PlayerName  = @param0 )", new List<object>() { name }) > 0) return true;
            else return false;
        }

        public static int PlayerPlanets(int id)
        {
            return DAL.GetInstance().GetInt("SELECT Count( OwnerID) FROM Planets Where OwnerId = @param0", new List<object>() { id });
        }
        public static int PlayerCulture(int id)
        {
            return (int)DAL.GetInstance().GetDouble("SELECT CurrentCulture FROM Players Where PlayerId = @param0", new List<object>() { id });
        }
        public static int MaxPopulationForPlanet(int s)
        {
            if (s < 2) return 5;
            else if (s < 4) return 6;
            else if (s < 6) return 7;
            else if (s < 8) return 8;
            else if (s < 10) return 9;
            else return s;
        }
        public static void PlayerCapital(int pId, out int sId, out int plId)
        {
            sId = -1; plId = -1;
            DataSet ds = DAL.GetInstance().GetData("SELECT SystemId, PlanetId  FROM Planets Where OwnerId = @param0 Order by populationLevel desc, Planets.PopToNextLevel ASC", new List<object>() { pId });
            if (ds.Tables.Count > 0)
                if (ds.Tables[0].Rows.Count > 0)
                {
                    sId = int.Parse(ds.Tables[0].Rows[0][0].ToString());
                    plId = int.Parse(ds.Tables[0].Rows[0][1].ToString());
                }
        }
        public static double GetPlayerCash(int id)
        {
            return GetPlayerFloat(id, "Cash");
        }
        public static int GetPlayerInt(int id, string property)
        {
            try
            {
                return DAL.GetInstance().GetInt("SELECT " + property + "  FROM Players Where PlayerId = @param0", new List<object>() { id });
            }
            catch (Exception)
            {
                StoredProcedures.InsertLog(DateTime.Now, "Get player int", "Request: " + id.ToString() + " " + property + " failed");
                return 0;
            }
        }
        public static double GetPlayerFloat(int id, string property)
        {
            try
            {
                return DAL.GetInstance().GetDouble("SELECT " + property + "  FROM Players Where PlayerId = @param0", new List<object>() { id });
            }
            catch (Exception)
            {
                StoredProcedures.InsertLog(DateTime.Now, "Get player float", "Request: " + id.ToString() + " " + property + " failed");
                return 0;
            }
        }
        public static int GetPlayerID(string name)
        {
            return DAL.GetInstance().GetInt("SELECT PlayerId FROM Players Where PlayerName = @param0", new List<object>() { name });
        }
        public static int GetPlayerSciencePerH(int pId)
        {
            try
            {
                return (int)DAL.GetInstance().GetDouble("SELECT    SUM(Labs) + SUM(PopulationLevel)  AS Expr2 FROM Planets GROUP BY OwnerID HAVING      (OwnerID = @param0)", new List<object>() { pId });
            }
            catch (Exception)
            {
                return 0;
            }
        }
        public static int GetPlayerProductionPerH(int pId)
        {
            try
            {
                return (int)DAL.GetInstance().GetDouble("SELECT    SUM(Factories) + SUM(PopulationLevel)  AS Expr2 FROM Planets GROUP BY OwnerID HAVING      (OwnerID = @param0)", new List<object>() { pId });
            }
            catch (Exception)
            {
                return 0;
            }
        }
        public static int GetPlayerCulturePerH(int pId)
        {
            try
            {
                return (int)DAL.GetInstance().GetDouble("SELECT  SUM(Cybernets) FROM Planets GROUP BY OwnerID HAVING      (OwnerID = @param0)", new List<object>() { pId });
            }
            catch (Exception)
            {
                return 0;
            }
        }
        public static double GetPlayerScience(int pId, int scienceID)
        {
            string cmd = "";
            switch (scienceID)
            {
                case 1:
                    cmd = "SELECT     Biology FROM  Players Where PlayerId = @param0"
                    ; break;
                case 2:
                    cmd = "SELECT     Economy FROM Players Where PlayerId = @param0"
                    ; break;
                case 3:
                    cmd = "SELECT     Energy FROM  Players Where PlayerId = @param0"
                    ; break;
                case 4:
                    cmd = "SELECT     Math FROM         Players Where PlayerId = @param0"
                    ; break;
                case 5:
                    cmd = "SELECT     Physics FROM         Players Where PlayerId = @param0"
                    ; break;
                case 6:
                    cmd = "SELECT     Social FROM         Players Where PlayerId = @param0"
                    ; break;
            }
            return DAL.GetInstance().GetDouble(cmd, new List<object>() { pId });
        }
        public static int GetPlayerFleetsOnAir(int pId)
        {
            return DAL.GetInstance().GetInt("Select Count(*) from Fleets Where OwnerId = @param0", new List<object>() { pId });
        }
        public static int GetPlayerSciencePerHWithBonus(int pId)
        {
            int sci = GetPlayerSciencePerH(pId);
            double bonus = GetBonusForScience(pId);
            return (int)(sci * (1 + bonus));
        }
        public static int GetPlayerCulturePerHWithBonus(int pId)
        {
            int cul = GetPlayerCulturePerH(pId);
            double bonus = GetBonusForCulture(pId);
            return (int)(cul * (1 + bonus));
        }
    };
}